/*
 * ============================================================================
 *
 *       Filename:  thread_cond_example.c
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  2014年03月19日 11时58分52秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  jianxi sun (jianxi), ycsunjane@gmail.com
 *   Organization:  
 *
 * ============================================================================
 */
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include <pthread.h>
#include <errno.h>
pthread_cond_t cond;
pthread_mutex_t mutex;

void *cond_example(void *str)
{
	printf("str:%s\n", str);
	strcpy(str, "xiaojuan");
	pthread_mutex_lock(&mutex);
	pthread_cond_signal(&cond);
	pthread_mutex_unlock(&mutex);

	return str;
}

void maketimeout(struct timespec *ts, struct timespec *delay)
{
	ts->tv_sec += delay->tv_sec;
	if((ts->tv_nsec += delay->tv_nsec) > 1000000000ull) {
		ts->tv_nsec = ts->tv_nsec - 1000000000ull;
		ts->tv_sec++;
	}
}

int main()
{
	pthread_t tid;
	pthread_cond_init(&cond, NULL);
	pthread_mutex_init(&mutex, NULL);

	char *arg = malloc(100);
	strcpy(arg,"jianxi");
	pthread_create(&tid, NULL, cond_example, arg);

	struct timespec ts, nowspec;
	ts.tv_sec = 5;
	ts.tv_nsec = 0;

	struct timeval now;
	gettimeofday(&now, NULL);
	nowspec.tv_sec = now.tv_sec;
	nowspec.tv_nsec = now.tv_usec * 1000;
	maketimeout(&nowspec, &ts);

	int ret;
	pthread_mutex_lock(&mutex);
	while(arg[0] != 'x') {
		ret = pthread_cond_timedwait(&cond, &mutex, &nowspec);
		if(ret == ETIMEDOUT) {
			printf("wait too long\n");
			return 0;
		}
	}
	printf("str:%s\n", arg);
	pthread_mutex_unlock(&mutex);

	char *retarg = NULL;
	pthread_join(tid, (void **)&retarg);
}
